/**
 * 
 */
package it.unicam.cs.cosy.bioshape.core.util.vcliptoxml;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.File; // Gestione dei files
import java.io.FileOutputStream;
import java.io.IOException; // Errori di I/O
import java.io.PrintStream; // Flusso per la stampa
import java.util.ArrayList;
import java.util.Iterator; // Strumento per la scanione di liste
import java.util.List; // Lista di oggetti
import java.util.Set;
import java.util.StringTokenizer;

import org.jdom.Attribute;
import org.jdom.DataConversionException;
import org.jdom.Document; // Documento XML
import org.jdom.Element; // Singolo elemento XML
import org.jdom.JDOMException; // Errori sulla gestione XML
import org.jdom.input.SAXBuilder; // Costruttore di documenti XML
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Provides methods to translate a shape specified in the named format used in
 * Brian Mirtich's original V-Clip implementation into the XML descriptio
 * accepted by BioShape in its input file.
 * 
 * @author luca
 * 
 */
public class ScanNamedToXMLTranslator {
    /*
     * File Chooser per la scelta del file xml contenente l'automa da leggere
     * e/o scrivere
     */
    private static JFileChooser fileChooser;;

    public static AtomicShape readVClipAtomicShape() throws IOException,
            JDOMException, AtomicShapeDescriptionException {
        int returnVal = fileChooser.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            String shapeName = JOptionPane.showInputDialog(null,
                    "Give a Name to This Shape");
            return readVClipAtomicShape(
                    fileChooser.getSelectedFile().getPath(), shapeName);
        } else
            return null;
    }

    public static AtomicShape readVClipAtomicShape(String fileName,
            String shapeName) throws IOException, JDOMException,
            AtomicShapeDescriptionException {
        ArrayList<Vertex> vertices = new ArrayList<Vertex>();
        ArrayList<Face> faces = new ArrayList<Face>();
        String name;
        // Stream di output sullo schemo
        PrintStream out = System.out;
        // Apro il File
        BufferedReader in = new BufferedReader(new FileReader(fileName));
        String line = in.readLine();
        System.out.println("Linea letta " + line );
        while (!line.startsWith("*")) {
            StringTokenizer st = new StringTokenizer(line);
//            if (st.countTokens() != 4)
//                throw new AtomicShapeDescriptionException(
//                        "Vertex with wrong number of coordinates");
            String vertexName = st.nextToken();
            double x = Double.parseDouble(st.nextToken());
            double y = Double.parseDouble(st.nextToken());
            double z = Double.parseDouble(st.nextToken());
            Vertex v = new Vertex(vertexName, x, y, z);
            vertices.add(v);
            line = in.readLine();
            System.out.println("Linea letta " + line );
        }
        // last line was "*"
        line = in.readLine();
        System.out.println("Linea letta " + line );
        while (line != null && !line.equals("")) {
            StringTokenizer st = new StringTokenizer(line);
//            if (st.countTokens() < 4)
//                throw new AtomicShapeDescriptionException(
//                        "Insufficient Vertices for a Face");
            String faceName = st.nextToken();
            ArrayList<String> components = new ArrayList<String>();
            while (st.hasMoreTokens())
                components.add(st.nextToken());
            Face f = new Face(faceName, components);
            faces.add(f);
            line = in.readLine();
            System.out.println("Linea letta " + line );
        }
        in.close();
        System.out.println("Chiuso File");
        return new AtomicShape(shapeName, vertices, faces);
    }

    public static void writeBioShapeXML(AtomicShape shape) throws IOException {
        int returnVal = fileChooser.showSaveDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION)
            writeBioShapeXML(shape, fileChooser.getSelectedFile().getPath());
    }

    public static void writeBioShapeXML(AtomicShape shape, String fileName)
            throws IOException {
        // Creazione della root
        Element root = new Element("atomicshape");
        // Inserisco la descrizione dell'automa
        Attribute shapeName = new Attribute("name", shape.getName());
        root.setAttribute(shapeName);
        ArrayList<Element> verticesElements = new ArrayList<Element>();
        for (Vertex v : shape.getVertices()) {
            Element ve = new Element("vertex");
            Attribute attr = new Attribute("name", v.getName());
            ve.setAttribute(attr);
            Element coord = new Element("coordinates");
            Attribute xAttr = new Attribute("x", "" + v.getCoordinates()[0]);
            Attribute yAttr = new Attribute("y", "" + v.getCoordinates()[1]);
            Attribute zAttr = new Attribute("z", "" + v.getCoordinates()[2]);
            coord.setAttribute(xAttr);
            coord.setAttribute(yAttr);
            coord.setAttribute(zAttr);
            ve.addContent(coord);
            verticesElements.add(ve);
        }
        root.addContent(verticesElements);
        ArrayList<Element> facesElements = new ArrayList<Element>();
        for (Face f : shape.getFaces()) {
            Element fe = new Element("face");
            Attribute attr = new Attribute("name", f.getName());
            fe.setAttribute(attr);
            ArrayList<Element> componentsElements = new ArrayList<Element>();
            for (String components : f.getComponents()) {
                Element component = new Element("vertex");
                component.addContent(components);
                componentsElements.add(component);
            }
            fe.addContent(componentsElements);
            facesElements.add(fe);
        }
        root.addContent(facesElements);

        /*
         * Scrittura del file XML
         */
        // Creo lo stream di output XML
        XMLOutputter xmlOut = new XMLOutputter();
        // Scelgo il formato
        xmlOut.setFormat(Format.getPrettyFormat());
        // Creo il file di output
        FileOutputStream file = new FileOutputStream(new File(fileName));
        // Scrivo il documento XML nel file di output
        xmlOut.output(new Document(root), file);
    }

    public static void translate() throws IOException, JDOMException,
            AtomicShapeDescriptionException {
        fileChooser = new JFileChooser();
        AtomicShape shape = readVClipAtomicShape();
        writeBioShapeXML(shape);
        fileChooser = null;
    }

    public static void main(String[] args) throws IOException, JDOMException,
            AtomicShapeDescriptionException {
        translate();
        System.exit(0);
    }

}
